﻿using System;
using System.Windows.Forms;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.WindowsDesktopEx.Base;

namespace UtilZ.Dotnet.WindowsDesktopEx.Winform
{
    internal partial class FNotify
    {
        private const double _PRE = 0.001d;

        private readonly NotifyItem _item;
        private readonly int _padding;
        private int _animalXOffset;
        private readonly double _opacityStep = -1;
        private NotifyStatus _notifyStatus = NotifyStatus.Starting;
        private bool _clickCloseButton = false;

        public FNotify(NotifyItem item, double opacityStep, int padding)
            : this()
        {
            this._item = item;
            if (item.BackgroundImage != null)
            {
                this.BackgroundImage = item.BackgroundImage;
                this.BackgroundImageLayout = item.BackgroundImageLayout;
            }
            else
            {
                this.BackColor = item.BackgroundColor;
            }

            if (item.Size.HasValue)
            {
                this.Size = item.Size.Value;
            }

            pictureBoxMsgType.Image = item.MesageImage;
            labelMsg.Text = item.Text;

            this._opacityStep = opacityStep;
            if (opacityStep > 0)
            {
                this.Opacity = 0.0d;
            }

            this.TopMost = true;

            this._padding = padding;
            this._animalXOffset = padding;
        }


        internal void UpdateLocaion(int totalHeight, int margin)
        {
            int x = Screen.PrimaryScreen.WorkingArea.Width - this._padding - this.Width + this._animalXOffset;
            int y = Screen.PrimaryScreen.WorkingArea.Height - totalHeight - this.Height - margin;
            this.Location = new System.Drawing.Point(x, y);
        }

        private void FNotify_Load(object sender, EventArgs e)
        {

        }



        private long _startTimestamp = -1;
        internal bool Check()
        {
            switch (this._notifyStatus)
            {
                case NotifyStatus.Starting:
                    if (this._startTimestamp < 0)
                    {
                        this._startTimestamp = TimeEx.GetTimestamp();
                    }

                    if (this._opacityStep > 0)
                    {
                        if (this._animalXOffset > 0)
                        {
                            int x = Screen.PrimaryScreen.WorkingArea.Width - this._padding - this.Width + this._animalXOffset--;
                            this.Location = new System.Drawing.Point(x, this.Location.Y);
                        }

                        if (1.0d - this.Opacity < _PRE)
                        {
                            if (this.Opacity < 1.0d)
                            {
                                this.Opacity = 1.0d;
                            }

                            this._notifyStatus = NotifyStatus.Wait;
                        }
                        else
                        {
                            var opacity = this.Opacity + this._opacityStep;
                            if (opacity - 1.0d > _PRE)
                            {
                                opacity = 1.0d;
                                this._notifyStatus = NotifyStatus.Wait;
                            }
                            this.Opacity = opacity;
                        }
                    }
                    else
                    {
                        this._notifyStatus = NotifyStatus.Wait;
                    }
                    break;
                case NotifyStatus.Wait:
                    if (TimeEx.GetTimestamp() - this._startTimestamp > this._item.Duration)
                    {
                        this._notifyStatus = NotifyStatus.Closing;
                    }
                    break;
                case NotifyStatus.Closing:
                    if (WinformHelper.MouseInControl(this))
                    {
                        //鼠标在窗口内
                        if (this._clickCloseButton)
                        {
                            //点了关闭按钮,直接慢慢关闭
                        }
                        else
                        {
                            if (this.Opacity < 1.0d)
                            {
                                this.Opacity = 1.0d;
                            }

                            return false;
                        }
                    }

                    if (this._opacityStep > 0)
                    {
                        //有动画就慢慢消失并关闭
                        int x = Screen.PrimaryScreen.WorkingArea.Width - this._padding - this.Width + this._animalXOffset++;
                        this.Location = new System.Drawing.Point(x, this.Location.Y);

                        var opacity = this.Opacity - this._opacityStep;
                        if (opacity < _PRE)
                        {
                            this.Opacity = 0.0d;
                            this.Close();
                            return true;
                        }

                        this.Opacity = opacity;
                    }
                    else
                    {
                        //无动画直接关闭
                        this.Close();
                    }

                    return false;
            }

            return false;
        }


        /// <summary>
        /// 点击关闭按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBoxClose_MouseClick(object sender, MouseEventArgs e)
        {
            this._notifyStatus = NotifyStatus.Closing;
            this._clickCloseButton = true;
        }

        private void FNotify_FormClosed(object sender, FormClosedEventArgs e)
        {
            this._item.Closed?.Invoke(this._item);
        }



        private void OnRaiseMouseClick()
        {
            this._item.MouseClick?.Invoke(this._item);
        }

        private void FNotify_MouseClick(object sender, MouseEventArgs e)
        {
            this.OnRaiseMouseClick();
        }

        private void pictureBoxMsgType_MouseClick(object sender, MouseEventArgs e)
        {
            this.OnRaiseMouseClick();
        }

        private void panel1_MouseClick(object sender, MouseEventArgs e)
        {
            this.OnRaiseMouseClick();
        }

        private void labelMsg_MouseClick(object sender, MouseEventArgs e)
        {
            this.OnRaiseMouseClick();
        }

    }
}
